﻿using System.Net;
using System.Net.Sockets;
using Microsoft.Extensions.Options;
using NModbus;
using qYun.ApiService.Models;
using YunHeModel=qYun.Shared.Models.YunHeModel;

namespace qYun.ApiService.Services;

/// <summary>
/// 
/// </summary>
public class YunheService:IYunheService
{
    private ILogger<YunheService> _logger;
    public required SystemConfig _config;
    public required IModbusMaster _master;
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="config"></param>
    public YunheService(ILogger<YunheService> logger,IOptions<SystemConfig> config)
    {
        _logger = logger;
        _config = config.Value;
        var sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        var yIp = _config.YunHe?.DeviceIp;
        var yPort = _config.YunHe?.DevicePort;
        if(yIp is null|| yPort is null)
        {
            _logger.LogError("云盒检测装置IP地址为空");
            return ;
        }
        // var serverFullAddr = new IPEndPoint(IPAddress.Parse(yIp), int.Parse(yPort));
        // sock.Connect(serverFullAddr);
        //
        // var factory = new ModbusFactory();
        // _master = factory.CreateMaster(sock);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public async Task<YunHeModel> GetDataAsync()
    {
        try
        {
            var model = new YunHeModel();
            const string slaveId = "1";
            await Task.Run(async () =>
            {
                var res = await _master.ReadHoldingRegistersAsync(byte.Parse(slaveId), 0x0000, 94);
                var i = 0;
                model.Temperature = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[1])), 0);
                i += 2;
                model.Density = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.DynamicViscosity = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.KinematicViscosity = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.KinematicViscosity40C = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.DielectricConstant = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.Saturation = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.MoistureContent = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.MoistureRatio = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationCriteria = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationLevel1 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationLevel2 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationLevel3 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationLevel4 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationLevel5 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationLevel6 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel1 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel2 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel3 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel4 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel5 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel6 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel7 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ContaminationParticleCountChannel8 = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.FerromagneticParticleCountLT70um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.FerromagneticParticleCount70to100um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.FerromagneticParticleCount100to200um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.FerromagneticParticleCount200to400um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.FerromagneticParticleCount400to800um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.FerromagneticParticleCountGT800um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.FerromagneticParticleTotalCount = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.NonFerromagneticParticle150to200um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.NonFerromagneticParticle200to400um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.NonFerromagneticParticle400to800um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.NonFerromagneticParticle800to1600um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.NonFerromagneticParticleGT1600um = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.NonFerromagneticParticleTotalCount = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.Conductivity = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.PowerState = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.BufferPoolTemperature = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.AmbientTemperature = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.InletOilPressure = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.InletOilTemperature = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);
                i += 2;
                model.ReservedUpgradeItem = BitConverter.ToSingle(BitConverter.GetBytes((int)(res[i] << 16 | res[i + 1])), 0);

                res = await _master.ReadHoldingRegistersAsync(byte.Parse(slaveId), 0x0058, 38);
                i = 0;
                model.USBStatus = (short)res[i];
                i += 1;
                model.WearExceedance = (short)res[i];
                i += 1;
                model.DielectricConstantExceedance = (short)res[i];
                i += 1;
                model.WaterContentExceedance = (short)res[i];
                i += 1;
                model.ConductivityAnomaly = (short)res[i];
                i += 1;
                model.SpareSwitchingValue = (short)res[i];
                i += 1;
                model.OilLeakageFlag = (short)res[i];
                i += 1;
                model.LinkageSignalStatus = (short)res[i];
                i += 1;
                model.KinematicViscosityAlarmStatus = (short)res[i];
                i += 1;
                model.TemperatureAlarmStatus = (short)res[i];
                i += 1;
                model.DensityAlarmStatus = (short)res[i];
                i += 1;
                model.WaterActivityAlarmStatus = (short)res[i];
                i += 1;
                model.MoistureRatioAlarmStatus = (short)res[i];
                i += 1;
                model.PPMAlarmStatus = (short)res[i];
                i += 1;
                model.DielectricAlarmStatus = (short)res[i];
                i += 1;
                model.FerromagneticAlarmStatus = (short)res[i];
                i += 1;
                model.NonFerromagneticAlarmStatus = (short)res[i];
                i += 1;
                model.KinematicViscosity40CAlarmStatus = (short)res[i];
                i += 1;
                model.KinematicViscosityUpperLimit = (short)res[i];
                i += 1;
                model.KinematicViscosityLowerLimit = (short)res[i];
                i += 1;
                model.TemperatureUpperLimit = (short)res[i];
                i += 1;
                model.TemperatureLowerLimit = (short)res[i];
                i += 1;
                model.DensityUpperLimit = (short)res[i];
                i += 1;
                model.DensityLowerLimit = (short)res[i];
                i += 1;
                model.WaterActivityUpperLimit = (short)res[i];
                i += 1;
                model.WaterActivityLowerLimit = (short)res[i];
                i += 1;
                model.MoistureRatioUpperLimit = (short)res[i];
                i += 1;
                model.MoistureRatioLowerLimit = (short)res[i];
                i += 1;
                model.PPMUpperLimit = (short)res[i];
                i += 1;
                model.PPMLowerLimit = (short)res[i];
                i += 1;
                model.DielectricConstantUpperLimit = (short)res[i];
                i += 1;
                model.DielectricConstantLowerLimit = (short)res[i];
                i += 1;
                model.FerromagneticParticleUpperLimit = (short)res[i];
                i += 1;
                model.FerromagneticParticleLowerLimit = (short)res[i];
                i += 1;
                model.NonFerromagneticParticleUpperLimit = (short)res[i];
                i += 1;
                model.NonFerromagneticParticleLowerLimit = (short)res[i];
                i += 1;
                model.KinematicViscosity40CUpperLimit = (short)res[i];
                i += 1;
                model.KinematicViscosity40CLowerLimit = (short)res[i];
            });
            return model;
        }
        catch (Exception e)
        {
            _logger.LogError(e,"云盒检测设备异常");
            return null;
        }
    }
}

/// <summary>
/// 
/// </summary>
public interface IYunheService
{
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public Task<YunHeModel> GetDataAsync();
}